#pragma once
#include <thread>
#include <iostream>
#include <string>
#include <queue>
 #include <pthread.h>
#include <vector>
#include <unistd.h>
#include "APILock.hpp"
#include <semaphore.h>

template <class T>
class RingQueue // 通过信号量实现线程安全的环形队列，最终实现生产者与消费者模型
{
    std::vector<T> _ringqueue;
    int _con_inudx = 0, _pro_inudx = 0;
    int _cap;
    sem_t _consem, _prosem;
    pthread_mutex_t _conmutex, _promutex;
    void lock(pthread_mutex_t *mutex)
    {
        pthread_mutex_lock(mutex);
    }
    void unlock(pthread_mutex_t *mutex)
    {
        pthread_mutex_unlock(mutex);
    }

public:
    RingQueue(int cap = 3)
        : _cap(cap),
          _ringqueue(cap)
    {
        pthread_mutex_init(&_conmutex, nullptr);
        pthread_mutex_init(&_promutex, nullptr);
        sem_init(&_consem, 0, 0);
        sem_init(&_prosem, 0, _cap);
    }
    void push(T &data)
    {
        sem_wait(&_prosem); //_prosem--
        lock(&_promutex);
        _ringqueue[_pro_inudx++] = data;
        _pro_inudx %= _cap;
        unlock(&_promutex);
        sem_post(&_consem); //_consem++
    }
    void pop(T *out)
    {
        sem_wait(&_consem); //_consem--
        lock(&_conmutex);
        *out = _ringqueue[_con_inudx++];
        _con_inudx %= _cap;
        unlock(&_conmutex);
        sem_post(&_prosem); //_prosem++
    }
    ~RingQueue()
    {
        sem_destroy(&_consem);
        sem_destroy(&_prosem);
        pthread_mutex_destroy(&_conmutex);
        pthread_mutex_destroy(&_promutex);
    }
};